package com.lu.component.crypto.utils;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import com.lu.component.crypto.config.CryptoProperties;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 加解密工具
 *
 * @author: zhanglu
 * @date: 2023/9/20 19:58
 * @modify: 修改人信息, 修改内容 2023/9/20 19:58
 */
public final class CryptoUtil {

    private static final AES aes = new AES(Mode.CBC, Padding.PKCS5Padding,
            CryptoProperties.SECRET_AES_KEY.getBytes(StandardCharsets.UTF_8), CryptoProperties.SECRET_AES_MIX.getBytes(StandardCharsets.UTF_8));

    private CryptoUtil() {
    }

    public static void main(String[] args) {
        List<String> keys = rsaGenKeyPair();
        String publicKey = keys.get(0);
        String privateKey = keys.get(1);
        System.out.println("私钥: " + privateKey);
        System.out.println("公钥: " + publicKey);
        String encrypt = rsaEncrypt("18120123118", privateKey, publicKey);
        System.out.println(encrypt);
        String decrypt = rsaDecrypt(encrypt, privateKey, publicKey);
        System.out.println(decrypt);
    }

    /**
     * 转换密钥
     *
     * @param key 加密密钥
     * @return Key
     * @since 2022年3月10日10点59分
     */
    private static SecretKey getKey(String key) {
        SecretKey secret = null;
        try {
            PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray());
            SecretKeyFactory factory = SecretKeyFactory.getInstance(SymmetricAlgorithm.PBEWithMD5AndDES.getValue());
            secret = factory.generateSecret(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return secret;
    }

    /**
     * RSA公钥加密
     *
     * @param data       数据
     * @return 密文
     */
    public static String aesEncrypt(String data) {
        return aes.encryptBase64(data, CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * RSA私钥解密
     *
     * @param data       数据
     * @return           明文
     */
    public static String aesDecrypt(String data) {
        return aes.decryptStr(data, CharsetUtil.CHARSET_UTF_8);
    }


    /**
     * 随机生成密钥对
     *
     * @throws NoSuchAlgorithmException
     */
    public static List<String> rsaGenKeyPair() {
        List<String> keyMap = new ArrayList<>();
        RSA rsa = SecureUtil.rsa();
        /*0表示公钥*/
        keyMap.add(rsa.getPublicKeyBase64());
        /*1表示私钥*/
        keyMap.add(rsa.getPrivateKeyBase64());
        return keyMap;
    }

    /**
     * RSA公钥加密
     *
     * @param data       数据
     * @param privateKey 私钥
     * @param publicKey  公钥
     * @return 密文
     */
    public static String rsaEncrypt(String data, String privateKey, String publicKey) {
        return SecureUtil.rsa(privateKey, publicKey).encryptBase64(data, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
    }

    /**
     * RSA私钥解密
     *
     * @param data       数据
     * @param privateKey 私钥
     * @param publicKey  公钥
     * @return           明文
     */
    public static String rsaDecrypt(String data, String privateKey, String publicKey) {
        return SecureUtil.rsa(privateKey, publicKey).decryptStr(data, KeyType.PrivateKey, CharsetUtil.CHARSET_UTF_8);
    }

}
